home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Libris Britannia 4
/
science library(b).zip
/
science library(b)
/
TECHNICA
/
COMPUTER
/
H254.ZIP
/
IRITSM3S.ZIP
/
POLY3D
/
POLY3D.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-03-03
|
25KB
|
733 lines
/*****************************************************************************
* Program to draw 3D object as wireframe from any ortographic view *
* Options: *
* 1. -c : Object is closed. If object is closed each edge is shared by two *
* polygons and therefore can bedrawn only once. *
* 2. -e #Edges : If the edges are order is specific way (like in DrawFn3D) *
* and only the k first edges of each polygons are to be displayed *
* use this option as -e k. *
* 3. -i : Internal edges. IRIT solid modeller may generate edges, which one *
* may not want to see (default). -i will draw all of them. *
* 4. -m : More flag, to print more imformation on input/errors. *
* Note all messages goes to STDOUT (not stderr!) as this program *
* works in graphic mode, and we can redirect stdout to a file. *
* 5. -n : Draw vertices normals if the data has them, otherwise ignore. *
* 6. -M : draw surfaces Mesh and curves control polygon. *
* 7. -I n : number of isolines for a given surface. *
* 8. -P : generate polygon for surfaces. *
* 9. -S n : log based 2 of number of samples per curve. *
* 10. -f FineNess : log based 2 of the fineness control of surface to *
* polygon subdivision. *
* 11. -4 : force 4 polygons per flat. Otherwise two. *
* 12. -z : Print current version, and some helpfull data. *
* *
* Note some of those options way be permanently set to a different default *
* using the configuration file "Poly3D.cfg" *
* *
* Usage: *
* Poly3D [-c] [-m] [-i] [-e #Edges] [-n] [-N] [-M] [-I n] [-P] [-S n] *
* [-f FineNess] [-4] [-z] Files *
* *
* Written by: Gershon Elber Ver 3.0, Aug 1990 *
*****************************************************************************/
#ifdef __MSDOS__
#include <stdlib.h>
#include <conio.h>
#include <dos.h>
#include <graphics.h>
#include <alloc.h>
#endif /* __MSDOS__ */
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "program.h"
#include "getarg.h"
#include "genmat.h"
#include "interact.h"
#include "graphgen.h"
#include "config.h"
#ifdef __TURBOC__ /* Malloc debug routine - only on TC++ 1.0 and above. */
#define __DEBUG_MALLOC__
#endif /* __TURBOC__ */
#ifdef __MSDOS__
#include "matherr.h"
#endif /* __MSDOS__ */
#ifdef __MSDOS__
extern unsigned int _stklen = 32766; /* Increase default stack size. */
#endif /* __MSDOS__ */
#ifdef NO_CONCAT_STR
static char *VersionStr =
"Poly3D Version 3.0, Gershon Elber,\n\
(C) Copyright 1989/90/91 Gershon Elber, Non commercial use only.";
#else
static char *VersionStr = "Poly3D " VERSION ", Gershon Elber, "
__DATE__ ", " __TIME__ "\n"
"(C) Copyright 1989/90/91 Gershon Elber, Non commercial use only.";
#endif /* NO_CONCAT_STR */
static char *CtrlStr =
"poly3d c%- m%- i%- e%-#Edges!d n%- N%- M%- P%- I%-#IsoLines!d S%-#SampPerCrv!d f%-FineNess!d 4%- z%- DFiles!*s";
static int
GlblNormalLenAux = NORMAL_DEFAULT_LENGTH,
GlblFineNess = 5,
GlblFourPerFlat = FALSE;
/* The following are setable variables (via configuration file poly3d.cfg). */
int
#if defined(__MSDOS__) || defined(DJGCC) /* Defaults for MSDOS intr_lib. */
GlblWindowFrameWidth = 8,
GlblViewFrameColor = INTR_COLOR_RED,
GlblViewBackColor = INTR_COLOR_BLACK,
GlblTransFrameColor = INTR_COLOR_GREEN,
GlblTransBackColor = INTR_COLOR_BLACK,
GlblStatusFrameColor = INTR_COLOR_RED,
GlblStatusBackColor = INTR_COLOR_BLACK,
GlblInputFrameColor = INTR_COLOR_RED,
GlblInputBackColor = INTR_COLOR_BLACK,
GlblDrawHeader = FALSE,
GlblSmoothTextScroll = FALSE,
GlblIntrSaveMethod = INTR_SAVE_DISK,
GlblMouseSensitivity = 10, /* Sensitivity control of mouse device. */
GlblJoystickExists = FALSE,
#endif /*__MSDOS__ || DJGCC */
#ifdef __MSDOS__
GlblGraphDriver = DETECT,
#endif /* __MSDOS__ */
GlblWasCtrlBrk = FALSE,
GlblMouseExists = TRUE,
GlblTransformMode = TRANS_SCREEN, /* Screen, Object trans. mode. */
GlblViewMode = VIEW_ORTHOGRAPHIC, /* Persp, Ortho etc. */
GlblDepthCue = TRUE, /* Activate depth cueing. */
GlblDrawSolid = FALSE, /* Use hardware Z buffer rendering. */
GlblInternal = FALSE,
GlblDoGraphics = TRUE,/* Control if running in graphics/text mode. */
GlblMore = FALSE,
GlblNumEdges = 0,
GlblDrawVNormal = FALSE,
GlblDrawPNormal = FALSE,
GlblClosedObject = FALSE,
GlblDrawSurfaceMesh = FALSE,
GlblDrawSurfacePoly = FALSE,
GlblNumOfIsolines = DEFAULT_NUM_OF_ISOLINES,
GlblSamplesPerCurve = DEFAULT_SAMPLES_PER_CURVE;
static char
*BGIDriverPath = NULL,
*SVGANameMode = NULL;
char
#ifdef __GL__
/* Preferance position and size of view and transformation windows. */
*GlblTransPrefPos = "455, 640, 520, 965",
*GlblViewPrefPos = "1, 450, 520, 965",
#endif /* __GL__ */
#if defined(__MSDOS__) || defined(DJGCC) /* Defaults for MSDOS intr_lib. */
*GlblViewWndwPos = "0.02, 0.02, 0.72, 0.98",
*GlblTransWndwPos = "0.75, 0.02, 0.98, 0.98",
*GlblStatusWndwPos = "",
*GlblInputWndwPos = "",
*GlblIntrSaveDisk = "d:\\",
#endif /* __MSDOS__ || DJGCC */
GlblFirstDataFileName[PATH_NAME_LEN]; /* Hold name of first data file. */
static long SaveTotalTime;
MatrixType CrntViewMat; /* This is the current view! */
RealType GlblNormalLen = 0.0; /* Scaler for normals if drawn. */
static ConfigStruct SetUp[] =
{
#if defined(__MSDOS__) || defined(DJGCC) /* Defaults for MSDOS intr_lib. */
{ "Joystick", (VoidPtr) &GlblJoystickExists, SU_BOOLEAN_TYPE },
{ "Mouse", (VoidPtr) &GlblMouseExists, SU_BOOLEAN_TYPE },
{ "MouseSensitivity", (VoidPtr) &GlblMouseSensitivity,SU_INTEGER_TYPE },
{ "WndwWidth", (VoidPtr) &GlblWindowFrameWidth,SU_INTEGER_TYPE },
{ "WndwHeader", (VoidPtr) &GlblDrawHeader, SU_BOOLEAN_TYPE },
{ "WndwViewClr", (VoidPtr) &GlblViewFrameColor, SU_INTEGER_TYPE },
{ "WndwTransClr", (VoidPtr) &GlblTransFrameColor, SU_INTEGER_TYPE },
{ "WndwViewPos", (VoidPtr) &GlblViewWndwPos, SU_STRING_TYPE },
{ "WndwTransPos", (VoidPtr) &GlblStatusWndwPos, SU_STRING_TYPE },
{ "WndwBackSave", (VoidPtr) &GlblIntrSaveMethod, SU_INTEGER_TYPE },
{ "WndwBackSavePath", (VoidPtr) &GlblIntrSaveDisk, SU_STRING_TYPE },
#endif /* __MSDOS__ || DJGCC */
#ifdef __MSDOS__
{ "SVGANameMode", (VoidPtr) &SVGANameMode, SU_STRING_TYPE },
{ "BGIDriverPath", (VoidPtr) &BGIDriverPath, SU_STRING_TYPE },
{ "GraphDriver", (VoidPtr) &GlblGraphDriver, SU_INTEGER_TYPE },
#endif /* __MSDOS__ */
#ifdef __GL__
{ "TransPrefPos", (VoidPtr) &GlblTransPrefPos, SU_STRING_TYPE },
{ "ViewPrefPos", (VoidPtr) &GlblViewPrefPos, SU_STRING_TYPE },
#endif /* __GL__ */
{ "FineNess", (VoidPtr) &GlblFineNess, SU_INTEGER_TYPE },
{ "FourPerFlat", (VoidPtr) &GlblFourPerFlat, SU_BOOLEAN_TYPE },
{ "ViewMode", (VoidPtr) &GlblViewMode, SU_INTEGER_TYPE },
{ "TransMode", (VoidPtr) &GlblTransformMode, SU_INTEGER_TYPE },
{ "ClosedObject", (VoidPtr) &GlblClosedObject, SU_BOOLEAN_TYPE },
{ "DepthCue", (VoidPtr) &GlblDepthCue, SU_BOOLEAN_TYPE },
{ "DrawSolid", (VoidPtr) &GlblDrawSolid, SU_BOOLEAN_TYPE },
{ "Internal", (VoidPtr) &GlblInternal, SU_BOOLEAN_TYPE },
{ "More", (VoidPtr) &GlblMore, SU_BOOLEAN_TYPE },
{ "NormalLength", (VoidPtr) &GlblNormalLenAux, SU_INTEGER_TYPE },
{ "DrawVNormal", (VoidPtr) &GlblDrawVNormal, SU_BOOLEAN_TYPE },
{ "DrawPNormal", (VoidPtr) &GlblDrawPNormal, SU_BOOLEAN_TYPE },
{ "NumOfEdges", (VoidPtr) &GlblNumEdges, SU_INTEGER_TYPE },
{ "NumOfIsolines", (VoidPtr) &GlblNumOfIsolines, SU_INTEGER_TYPE },
{ "SamplesPerCurve", (VoidPtr) &GlblSamplesPerCurve, SU_INTEGER_TYPE },
{ "DrawSurfaceMesh", (VoidPtr) &GlblDrawSurfaceMesh, SU_BOOLEAN_TYPE },
{ "DrawSurfacePoly", (VoidPtr) &GlblDrawSurfacePoly, SU_BOOLEAN_TYPE } };
#define NUM_SET_UP (sizeof(SetUp) / sizeof(ConfigStruct))
static IPObjectStruct *MainGetDataFiles(char **DataFileNames, int NumOfDataFiles);
static IPPolygonStruct *Curve2Polylines(CagdCrvStruct *Crv);
static IPPolygonStruct *Surface2Polylines(CagdSrfStruct *Srf);
/*****************************************************************************
* Main routine - Read Parameter line and do what you need... *
*****************************************************************************/
void
#ifdef __MSDOS__
cdecl /* So we can use -rp in Borland 3.0 (parameters in registers.). */
#endif /* __MSDOS__ */
main(int argc, char **argv)
{
int Error,
EdgesFlag = FALSE,
VerFlag = FALSE,
IsoLinesFlag = FALSE,
SamplesPerCurveFlag = FALSE,
NumFiles = 0,
FineNessFlag = FALSE;
char
**FileNames = NULL;
IPObjectStruct *PObjects;
SaveTotalTime = time(NULL);
#ifdef __MSDOS__
ctrlbrk((int cdecl (*)()) MyExit); /* Kill process if ^C. */
#endif /* __MSDOS__ */
#ifdef __MSDOS__
MathErrorSetUp(ME_KILL, NULL); /* Kill process if math error occurs! */
#endif /* __MSDOS__ */
Config("poly3d", SetUp, NUM_SET_UP); /* Read config. file if exists. */
if ((Error = GAGetArgs(argc, argv, CtrlStr,
&GlblClosedObject, &GlblMore, &GlblInternal, &EdgesFlag,
&GlblNumEdges, &GlblDrawVNormal, &GlblDrawPNormal,
&GlblDrawSurfaceMesh, &GlblDrawSurfacePoly,
&IsoLinesFlag, &GlblNumOfIsolines,
&SamplesPerCurveFlag, &GlblSamplesPerCurve,
&FineNessFlag, &GlblFineNess,
&GlblFourPerFlat, &VerFlag, &NumFiles, &FileNames)) != 0) {
GAPrintErrMsg(Error);
GAPrintHowTo(CtrlStr);
exit(1);
}
if (VerFlag) {
fprintf(stderr, "\n%s\n\n", VersionStr);
GAPrintHowTo(CtrlStr);
ConfigPrint(SetUp, NUM_SET_UP);
exit(0);
}
if (!NumFiles) {
fprintf(stderr, "No data file names where given, exit.\n");
GAPrintHowTo(CtrlStr);
exit(1);
}
GlblNormalLen = ((RealType) GlblNormalLenAux) / NORMAL_SCALER_LENGTH;
strcpy(GlblFirstDataFileName, FileNames[0]);/* Save name of first file. */
/* Get the data files: */
IritPrsrPolyListCirc = FALSE;
PObjects = MainGetDataFiles(FileNames, NumFiles);
if (GlblViewMode != VIEW_PERSPECTIVE)
GlblViewMode = IritPrsrWasPrspMat ? VIEW_PERSPECTIVE :
VIEW_ORTHOGRAPHIC;
/* If no limit on num of edges set to maximum. Else increase count by */
/* one as we count vertices and n vertices bounds n-1 edges. */
if (GlblNumEdges == 0)
GlblNumEdges = 32767;
else
GlblNumEdges++;
#ifdef __MSDOS__
GGInstallBGI(BGIDriverPath, SVGANameMode);
GGInitGraph(GlblGraphDriver, TRUE); /* Initiate the graphic driver. */
#else
#ifdef DJGCC
GGInitGraph(0, TRUE); /* Initiate the graphic driver. */
#else
GGInitGraph(argc, argv, TRUE, TRUE); /* Initiate the graphic driver. */
#endif /* DJGCC */
#endif /* __MSDOS__ */
InteractGeomObject(PObjects);
MyExit(0);
}
/*****************************************************************************
* Main routine to read the data description files: *
* Returns pointer to pointers on FileDescription structures (one per file). *
*****************************************************************************/
static IPObjectStruct *MainGetDataFiles(char **DataFileNames, int NumOfDataFiles)
{
int i;
char *ErrorMsg;
FILE *f;
IPObjectStruct *PObj, *PObjTail,
*PObjHead = NULL;
for (i = 0; i < NumOfDataFiles; i++) {
if (GlblMore) fprintf(stderr, "Reading data file %s\n", *DataFileNames);
#if defined(__MSDOS__) || defined(DJGCC)
if ((f = fopen(*DataFileNames, "rt")) == NULL) { /* Open the file. */
#else
if ((f = fopen(*DataFileNames, "r")) == NULL) { /* Open the file. */
#endif /* __MSDOS__ || DJGCC */
fprintf(stderr, "Can't open data file %s\n", *DataFileNames);
exit(1);
}
if ((PObj = IritPrsrGetObjects(f)) != NULL) { /* Get the data file. */
PObjTail = PObj;
while (PObjTail -> Pnext) PObjTail = PObjTail -> Pnext;
PObjTail -> Pnext = PObjHead;
PObjHead = PObj;
}
if (GlblMore && IritPrsrParseError(&ErrorMsg))
fprintf(stderr, "File %s, %s\n", *DataFileNames, ErrorMsg);
fclose(f); /* Close the file. */
DataFileNames++; /* Skip to next file name. */
}
if (PObjHead == NULL) {
fprintf(stderr, "No data found.\n");
exit(1);
}
return PObjHead;
}
/*****************************************************************************
* Routine to convert all surfaces/curves into polylines as follows: *
* Curves are converted to single polyline with SamplesPerCurve samples. *
* Surface are converted into GlblNumOfIsolines curves in each axes, each *
* handled as Curves above. The polylines are saved in the appropriate *
* surface/curve slots. *
*****************************************************************************/
IPObjectStruct *IritPrsrProcessFreeForm(IPObjectStruct *CrvObjs,
IPObjectStruct *SrfObjs)
{
CagdCrvStruct *Crv, *Crvs;
CagdSrfStruct *Srf, *Srfs;
IPObjectStruct *PObj, *PPolyObj;
IPPolygonStruct *PPolygon, *PPolygonTemp;
if (CrvObjs == NULL && SrfObjs == NULL) return NULL;
/* Make sure requested format is something reasonable. */
if (GlblNumOfIsolines < 2) {
GlblNumOfIsolines = 2;
if (GlblMore)
fprintf(stderr,
"NumOfIsolines is less than 2, 2 picked instead.\n");
}
if (GlblSamplesPerCurve < 1) {
GlblSamplesPerCurve = 1;
if (GlblMore)
fprintf(stderr,
"SamplesPerCurve is less than 1, 1 picked instead.\n");
}
if (GlblSamplesPerCurve > CAGD_MAX_BEZIER_CACHE_ORDER) {
GlblSamplesPerCurve = CAGD_MAX_BEZIER_CACHE_ORDER;
if (GlblMore)
fprintf(stderr,
"Log2 SamplesPerCurve is more than %d, %d picked instead.\n",
CAGD_MAX_BEZIER_CACHE_ORDER, CAGD_MAX_BEZIER_CACHE_ORDER);
}
BzrCrvSetCache(GlblSamplesPerCurve, TRUE); /* Set up the bezier cache. */
if (CrvObjs) {
for (PObj = CrvObjs; PObj != NULL; PObj = PObj -> Pnext) {
Crvs = PObj -> U.PCrvs;
PObj -> FFPolylines = PPolyObj = IritPrsrNewObjectStruct();
*PPolyObj = *PObj; /* Copy all its attributes. */
PPolyObj -> U.PPolygon = NULL;
PPolyObj -> Type = IP_OBJ_POLY;
for (Crv = Crvs; Crv != NULL; Crv = Crv -> Pnext) {
PPolygon = PPolygonTemp = Curve2Polylines(Crv);
while (PPolygonTemp -> Pnext)
PPolygonTemp = PPolygonTemp -> Pnext;
PPolygonTemp -> Pnext = PPolyObj -> U.PPolygon;
PPolyObj -> U.PPolygon = PPolygon;
}
}
}
if (SrfObjs) {
for (PObj = SrfObjs; PObj != NULL; PObj = PObj -> Pnext) {
Srfs = PObj -> U.PSrfs;
PObj -> FFPolylines = PPolyObj = IritPrsrNewObjectStruct();
*PPolyObj = *PObj; /* Copy all its attributes. */
PPolyObj -> U.PPolygon = NULL;
PPolyObj -> Type = IP_OBJ_POLY;
for (Srf = Srfs; Srf != NULL; Srf = Srf -> Pnext) {
PPolygon = PPolygonTemp = Surface2Polylines(Srf);
while (PPolygonTemp -> Pnext)
PPolygonTemp = PPolygonTemp -> Pnext;
PPolygonTemp -> Pnext = PPolyObj -> U.PPolygon;
PPolyObj -> U.PPolygon = PPolygon;
}
/* IF polygons were actually created, make sure we would not */
/* create then again... */
if (GlblDrawSurfacePoly)
PObj -> FFPolygons = PObj -> FFPolylines;
}
}
if (SrfObjs == NULL)
return CrvObjs;
else if (CrvObjs == NULL)
return SrfObjs;
else {
for (PObj = SrfObjs; PObj -> Pnext != NULL; PObj = PObj -> Pnext);
PObj -> Pnext = CrvObjs;
return SrfObjs;
}
}
/*****************************************************************************
* Routine to convert a single curve into a polyline with SamplesPerCurve *
* samples, into a polyline object. *
*****************************************************************************/
static IPPolygonStruct *Curve2Polylines(CagdCrvStruct *Crv)
{
int i, j, n;
IPVertexStruct *V,
*VHead = NULL,
*VTail = NULL;
IPPolygonStruct *P,
*PHead = NULL;
CagdPolylineStruct *CagdPoly,
*CagdPolyHead = CagdCrv2Polyline(Crv, GlblSamplesPerCurve);
if (GlblDrawSurfaceMesh) {
CagdPoly = CagdCrv2CtrlPoly(Crv);
CagdPoly -> Pnext = CagdPolyHead;
CagdPolyHead = CagdPoly;
}
for (CagdPoly = CagdPolyHead;
CagdPoly != NULL;
CagdPoly = CagdPoly -> Pnext) {
n = CagdPoly -> Length;
for (i = 0, VHead = NULL; i < n; i++) { /* Convert to vertices. */
V = IritPrsrNewVertexStruct();
for (j = 0; j < 3; j++) /* Convert to our format. */
V -> Coord[j] = CagdPoly -> Polyline[i].Pt[j];
if (VHead) {
VTail -> Pnext = V;
VTail = V;
}
else
VHead = VTail = V;
}
P = IritPrsrNewPolygonStruct();
P -> PVertex = VHead;
P -> Type = IP_POLYLINE;
P -> Pnext = PHead;
PHead = P;
}
CagdPolylineFreeList(CagdPoly);
return PHead;
}
#ifdef __GL__
/*****************************************************************************
* Routine to convert a single surface into polygons with GlblFineNess as *
* sample control, and GlblFourPerFlat controlling # of polys per bilinear. *
*****************************************************************************/
IPPolygonStruct *Surface2Polygons(CagdSrfStruct *Srf)
{
int i, j;
IPVertexStruct *V, *VHead,
*VTail = NULL;
IPPolygonStruct *P,
*PHead = NULL;
CagdPolygonStruct *CagdPolygon,
*CagdPolygonHead = CagdSrf2Polygons(Srf, 1 << GlblFineNess, TRUE,
GlblFourPerFlat);
for (CagdPolygon = CagdPolygonHead, VHead = NULL;
CagdPolygon != NULL;
CagdPolygon = CagdPolygon -> Pnext) {
/* All polygons are triangles! */
for (i = 0, VHead = NULL; i < 3; i++) { /* Convert to vertices. */
V = IritPrsrNewVertexStruct();
IP_SET_VRTX_NORMAL(V); /* This vertex has normal. */
for (j = 0; j < 3; j++) /* Convert to our format. */
V -> Coord[j] = CagdPolygon -> Polygon[i].Pt[j];
for (j = 0; j < 3; j++)
V -> Normal[j] = CagdPolygon -> Normal[i].Vec[j];
if (VHead) {
VTail -> Pnext = V;
VTail = V;
}
else
VHead = VTail = V;
}
P = IritPrsrNewPolygonStruct();
P -> PVertex = VHead;
P -> Type = IP_POLYGON;
P -> Pnext = PHead;
PHead = P;
}
CagdPolygonFreeList(CagdPolygonHead);
return PHead;
}
#endif /* __GL__ */
/*****************************************************************************
* Routine to convert a single surface into a polylines with SamplesPerCurve *
* samples, NumOfIsolines isolines into a polyline object list. *
* If surface is to be approximated as polygons GlblFineNess and *
* GlblFourPerFlat controls this approximation. *
*****************************************************************************/
static IPPolygonStruct *Surface2Polylines(CagdSrfStruct *Srf)
{
int i, j, n;
IPVertexStruct *V,
*VHead = NULL,
*VTail = NULL;
IPPolygonStruct *P,
*PHead = NULL;
CagdPolylineStruct *CagdPolyline, *CagdPolylineTemp,
*CagdPolylineHead = NULL;
CagdPolygonStruct *CagdPolygon,
*CagdPolygonHead = NULL;
/* Note we compute normals in msdos only on demand. On unix we always */
/* compute them as they are also used in shading. */
if (GlblDrawSurfacePoly)
CagdPolygonHead = CagdSrf2Polygons(Srf, 1 << GlblFineNess,
#if defined(__MSDOS__) || defined(DJGCC)
GlblDrawVNormal, GlblFourPerFlat);
#else
TRUE, GlblFourPerFlat);
#endif /* __MSDOS__ || DJGCC */
else
CagdPolylineHead = CagdSrf2Polylines(Srf, GlblNumOfIsolines,
GlblSamplesPerCurve);
if (GlblDrawSurfaceMesh) {
CagdPolyline = CagdPolylineTemp = CagdSrf2CtrlMesh(Srf);
if (CagdPolylineTemp)
while (CagdPolylineTemp -> Pnext)
CagdPolylineTemp = CagdPolylineTemp -> Pnext;
CagdPolylineTemp -> Pnext = CagdPolylineHead;
CagdPolylineHead = CagdPolyline;
}
for (CagdPolyline = CagdPolylineHead;
CagdPolyline != NULL;
CagdPolyline = CagdPolyline -> Pnext) {
n = CagdPolyline -> Length;
for (i = 0, VHead = NULL; i < n; i++) { /* Convert to vertices. */
V = IritPrsrNewVertexStruct();
for (j = 0; j < 3; j++) /* Convert to our format. */
V -> Coord[j] = CagdPolyline -> Polyline[i].Pt[j];
if (VHead) {
VTail -> Pnext = V;
VTail = V;
}
else
VHead = VTail = V;
}
P = IritPrsrNewPolygonStruct();
P -> PVertex = VHead;
P -> Type = IP_POLYLINE;
P -> Pnext = PHead;
PHead = P;
}
CagdPolylineFreeList(CagdPolylineHead);
for (CagdPolygon = CagdPolygonHead, VHead = NULL;
CagdPolygon != NULL;
CagdPolygon = CagdPolygon -> Pnext) {
/* All polygons are triangles! */
for (i = 0, VHead = NULL; i < 3; i++) { /* Convert to vertices. */
V = IritPrsrNewVertexStruct();
IP_SET_VRTX_NORMAL(V); /* This vertex has normal. */
for (j = 0; j < 3; j++) /* Convert to our format. */
V -> Coord[j] = CagdPolygon -> Polygon[i].Pt[j];
for (j = 0; j < 3; j++)
V -> Normal[j] = CagdPolygon -> Normal[i].Vec[j] * GlblNormalLen;
if (VHead) {
VTail -> Pnext = V;
VTail = V;
}
else
VHead = VTail = V;
}
P = IritPrsrNewPolygonStruct();
P -> PVertex = VHead;
P -> Type = IP_POLYGON;
P -> Pnext = PHead;
PHead = P;
}
CagdPolygonFreeList(CagdPolygonHead);
return PHead;
}
#ifdef __DEBUG_MALLOC__
/*****************************************************************************
* My Routine to allocate dynamic memory. All program requests must call this *
* routine (no direct call to malloc). Dies if no memory. *
*****************************************************************************/
static void AllocError(const char *Msg, VoidPtr *p)
{
fprintf(stderr, "%s, Ptr = %p\n", Msg, p);
MyExit(3);
}
#endif /* __DEBUG_MALLOC__ */
/*****************************************************************************
* My Routine to allocate dynamic memory. All program requests must call this *
* routine (no direct call to malloc). Dies if no memory. *
*****************************************************************************/
VoidPtr MyMalloc(unsigned size)
{
static int Count = 0;
VoidPtr p;
#ifdef __MSDOS__
if (Count++ == 50) {
Count = 0;
fprintf(stderr, "Core left: %ldk \r", coreleft() / 1024);
}
#endif /* __MSDOS__ */
if ((p = malloc(size)) != NULL) return p;
fprintf(stderr, "Not enough memory, exit.\n");
MyExit(2);
return NULL; /* Make warnings silent. */
}
/*****************************************************************************
* My Routine to free dynamic memory. All program requests must call this *
* routine (no direct call to free). *
*****************************************************************************/
void MyFree(VoidPtr p)
{
#ifdef __DEBUG_MALLOC__
switch (heapchecknode(p)) {
case _HEAPCORRUPT:
AllocError("Heap is corrupted", p);
break;
case _BADNODE:
AllocError("Attempt to free a bogus pointer", p);
break;
case _FREEENTRY:
AllocError("Attempt to free an already freed pointer", p);
break;
case _USEDENTRY:
break;
default:
AllocError("Allocation error", p);
break;
}
#endif /* __DEBUG_MALLOC__ */
free(p);
}
/*****************************************************************************
* Trap Cagd_lib errors right here. *
*****************************************************************************/
void CagdFatalError(CagdFatalErrorType ErrID)
{
char
*ErrorMsg = CagdDescribeError(ErrID);
GGCloseGraph(); /* Close the graphic driver. */
fprintf(stderr, "CAGD_LIB: %s", ErrorMsg);
exit(-1);
}
/*****************************************************************************
* My exit routine. *
*****************************************************************************/
void MyExit(int ExitCode)
{
GGCloseGraph(); /* Close the graphic driver. */
#ifdef __MSDOS__
fprintf(stderr,
"\nPoly3D: Total RealTime %ld seconds, Core left %ldk.\n",
time(NULL) - SaveTotalTime, coreleft() / 1024);
#else
fprintf(stderr,
"\nPoly3D: Total RealTime %ld seconds.\n",
time(NULL) - SaveTotalTime);
#endif /* __MSDOS__ */
exit(ExitCode);
}